home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / peak / context.pyo (.txt) < prev   
Python Compiled Bytecode  |  2008-10-13  |  28KB  |  894 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. import contextlib
  5. import sys
  6. from thread import get_ident
  7. from peak.util.decorators import cache_source, classy
  8. __all__ = [
  9.     'Service',
  10.     'replaces',
  11.     'setting',
  12.     'InputConflict',
  13.     'DynamicRuleError',
  14.     'State',
  15.     'Action',
  16.     'resource',
  17.     'registry',
  18.     'new',
  19.     'empty',
  20.     'lookup',
  21.     'manager',
  22.     'reraise',
  23.     'with_',
  24.     'call_with',
  25.     'ScopeError',
  26.     'resource_registry']
  27. _in_place = '__iadd__ __isub__ __imul__ __idiv__ __itruediv__ __ifloordiv__\n__imod__ __ipow__ __ilshift__ __irshift__ __iand__ __ixor__ __ior__'.split()
  28. _ignore = dict.fromkeys('\n    __name__ __module__ __return__ __slots__ get __init__ __metaclass__ __doc__\n    __call__ __new__'.split() + _in_place).__contains__
  29.  
  30. def _no_in_place(self, *args):
  31.     raise TypeError('In-place operators (other than <<=) cannot be performed on a service class')
  32.  
  33.  
  34. def _ilshift(cls, factory):
  35.     State[cls] = factory
  36.     return cls
  37.  
  38.  
  39. def _mod(cls, expr):
  40.     return 'lambda: ' + expr
  41.  
  42. _std_attrs = []([ (k, _no_in_place) for k in _in_place ], __ilshift__ = _ilshift, __mod__ = _mod)
  43.  
  44. def redirect_attribute(cls, name, payload):
  45.     setattr(type(cls), name, (property,)(((lambda s: getattr(s.get(), name)),), ((lambda s, v: setattr(s.get(), name, v)),), (lambda s: delattr(s.get(), name))))
  46.  
  47.  
  48. class _ClassDelegate(classy):
  49.     __slots__ = ()
  50.     get = None
  51.     
  52.     def __class_init__(cls, name, bases, cdict, supr):
  53.         meta = type(cls)
  54.         if getattr(meta, '__for_class__', None) is not cls:
  55.             cls.__class__ = meta = type(meta)(cls.__name__ + 'Class', (meta,), dict(_std_attrs, __module__ = cls.__module__, __for_class__ = cls))
  56.         
  57.         supr()(cls, name, bases, cdict, supr)
  58.         if 'get' not in cdict:
  59.             cls.get = staticmethod(classmethod(lookup).__get__(None, cls))
  60.         
  61.         for k, v in cdict.items():
  62.             if not isinstance(k, basestring):
  63.                 continue
  64.             
  65.             if not isinstance(v, (classmethod, staticmethod)) and not _ignore(k):
  66.                 redirect_attribute(cls, k, v)
  67.                 continue
  68.         
  69.  
  70.     __class_init__ = classmethod(__class_init__)
  71.  
  72.  
  73. class State(_ClassDelegate):
  74.     
  75.     def __new__(cls, *rules, **attrs):
  76.         if not attrs or object.__new__(cls):
  77.             pass
  78.         return empty()
  79.  
  80.     
  81.     def __init__(self, **attrs):
  82.         self.__dict__.update(attrs)
  83.  
  84.     
  85.     def __getitem__(self, key):
  86.         return self.getRule(key)
  87.  
  88.     
  89.     def __setitem__(self, key, rule):
  90.         return self.setRule(key, rule)
  91.  
  92.     
  93.     def swap(self):
  94.         raise NotImplementedError("Can't switch to the root state")
  95.  
  96.     
  97.     def child(self, *rules):
  98.         raise NotImplementedError
  99.  
  100.     
  101.     def __enter__(self):
  102.         raise NotImplementedError("Can't enter the root state")
  103.  
  104.     
  105.     def __exit__(self, typ, val, tb):
  106.         raise NotImplementedError("Can't exit the root state")
  107.  
  108.     
  109.     def on_exit(self, callback):
  110.         raise NotImplementedError
  111.  
  112.     
  113.     def get(key = None):
  114.         raise NotImplementedError
  115.  
  116.     get = staticmethod(get)
  117.     parent = None
  118.  
  119.  
  120. class InputConflict(Exception):
  121.     pass
  122.  
  123.  
  124. class DynamicRuleError(Exception):
  125.     pass
  126.  
  127.  
  128. class ScopeError(Exception):
  129.     pass
  130.  
  131. _exc_info = { }
  132. nones = (None, None, None)
  133.  
  134. def _swap_exc_info(data):
  135.     this_thread = get_ident()
  136.     old = _exc_info.get(this_thread, nones)
  137.     _exc_info[this_thread] = data
  138.     return old
  139.  
  140.  
  141. def new():
  142.     return State.child()
  143.  
  144.  
  145. def _let_there_be_state():
  146.     states = { }
  147.     
  148.     def _swap(what):
  149.         this_thread = get_ident()
  150.         old = states.setdefault(this_thread, what)
  151.         states[this_thread] = what
  152.         return old
  153.  
  154.     
  155.     def lookup(key):
  156.         
  157.         try:
  158.             (state, getRule, lookup, child) = states[get_ident()]
  159.         except KeyError:
  160.             empty().swap()
  161.             (state, getRule, lookup, child) = states[get_ident()]
  162.  
  163.         return lookup(key)
  164.  
  165.     
  166.     def get(key = ((None, (None,)), None)):
  167.         
  168.         try:
  169.             (state, getRule, lookup, child) = states[get_ident()]
  170.         except KeyError:
  171.             empty().swap()
  172.             (state, getRule, lookup, child) = states[get_ident()]
  173.  
  174.         if key is None:
  175.             return state
  176.         
  177.         return getRule(key)
  178.  
  179.     
  180.     def disallow(key):
  181.         raise DynamicRuleError('default rule or exit function tried to read dynamic state', key)
  182.  
  183.     
  184.     def empty():
  185.         state = new_state(root_getrule)
  186.         state.parent = root
  187.         return state
  188.  
  189.     
  190.     def new_state(inherit = None, inheritedDistances = None, propagate = (None, (None, None, None), None, None, None)):
  191.         buffer = { }
  192.         rules = { }
  193.         values = { }
  194.         distances = { }
  195.         computing = { }
  196.         get_stack = computing.get
  197.         set_stack = computing.setdefault
  198.         
  199.         def getRule(key):
  200.             
  201.             try:
  202.                 rule = rules[key]
  203.             except KeyError:
  204.                 
  205.                 try:
  206.                     rule = buffer[key]
  207.                 except KeyError:
  208.                     rule = buffer.setdefault(key, __fallback(key))
  209.  
  210.                 rule = rules.setdefault(key, rule)
  211.                 if key not in distances:
  212.                     if inheritedDistances is not None and inherit(key) == rule:
  213.                         distances.setdefault(key, inheritedDistances[key] + 1)
  214.                     else:
  215.                         distances[key] = 0
  216.                 
  217.             except:
  218.                 key not in distances
  219.  
  220.             if computing:
  221.                 stack = get_stack(get_ident())
  222.                 if stack:
  223.                     stack[-1] = min(stack[-1], distances[key])
  224.                 
  225.             
  226.             return rule
  227.  
  228.         
  229.         def setRule(key, rule):
  230.             buffer[key] = rule
  231.             old = rules.get(key, rule)
  232.             if old is not rule and old != rule:
  233.                 raise InputConflict(key, old, rule)
  234.             
  235.  
  236.         
  237.         def getValue(key):
  238.             
  239.             try:
  240.                 value = values[key]
  241.             except KeyError:
  242.                 this_thread = get_ident()
  243.                 rule = getRule(key)
  244.                 stack = set_stack(this_thread, [])
  245.                 stack.append(distances[key])
  246.                 
  247.                 try:
  248.                     value = key.__apply__(key, rule)
  249.                 finally:
  250.                     distance = stack.pop()
  251.                     if not stack:
  252.                         del computing[this_thread]
  253.                     else:
  254.                         stack[-1] = min(stack[-1], distance)
  255.  
  256.                 value = publish(distance, key, value)
  257.  
  258.             if computing:
  259.                 stack = get_stack(get_ident())
  260.                 if stack:
  261.                     stack[-1] = min(stack[-1], distances[key])
  262.                 
  263.             
  264.             return value
  265.  
  266.         
  267.         def publish(distance, key, value):
  268.             distances[key] = distance
  269.             if distance and propagate:
  270.                 value = propagate(distance - 1, key, value)
  271.             
  272.             return values.setdefault(key, value)
  273.  
  274.         
  275.         def child():
  276.             s = new_state(getRule, distances, publish)
  277.             s.parent = this
  278.             return s
  279.  
  280.         
  281.         def __fallback(key):
  282.             old = _swap(disabled)
  283.             
  284.             try:
  285.                 return key.__fallback__(inherit, key)
  286.             finally:
  287.                 _swap(old)
  288.  
  289.  
  290.         
  291.         def swap():
  292.             if exited:
  293.                 raise ScopeError("Can't switch to an exited state")
  294.             
  295.             (state, get, lookup, old_child) = old = _swap(enabled)
  296.             if lookup is disallow:
  297.                 _swap(old)
  298.                 raise DynamicRuleError('default rule or exit function tried to change states')
  299.             
  300.             return state
  301.  
  302.         
  303.         def __enter__():
  304.             if my_parent or exited:
  305.                 raise ScopeError("Can't re-enter a previously-entered state")
  306.             elif active_child:
  307.                 raise ScopeError('State already has an active child')
  308.             elif get() is this:
  309.                 raise ScopeError('State is already current')
  310.             
  311.             (parent, xx, xx, parents_child) = old = states[get_ident()]
  312.             if parents_child:
  313.                 raise ScopeError('Current state already has an active child')
  314.             
  315.             swap()
  316.             my_parent.append(old)
  317.             parents_child.append(this)
  318.             return this
  319.  
  320.         
  321.         def __exit__(typ, val, tb):
  322.             if exited:
  323.                 raise ScopeError('State already exited')
  324.             elif not my_parent:
  325.                 raise ScopeError("State hasn't been entered yet")
  326.             elif active_child:
  327.                 raise ScopeError("Nested state(s) haven't exited yet")
  328.             elif get() is not this:
  329.                 raise ScopeError("Can't exit a non-current state")
  330.             
  331.             parents_child = my_parent[0][-1]
  332.             _swap(my_parent.pop())
  333.             parents_child.pop()
  334.             exited.append(1)
  335.             values.clear()
  336.             return call_exitfuncs(typ, val, tb)
  337.  
  338.         active_child = []
  339.         my_parent = []
  340.         exited = []
  341.         exit_functions = []
  342.         
  343.         def call_exitfuncs(typ, val, tb):
  344.             old = _swap(disabled)
  345.             
  346.             try:
  347.                 for func in exit_functions:
  348.                     
  349.                     try:
  350.                         func(typ, val, tb)
  351.                     continue
  352.                     (typ, val, tb) = sys.exc_info()
  353.                     continue
  354.  
  355.             finally:
  356.                 _swap(old)
  357.                 del typ
  358.                 del val
  359.                 del tb
  360.  
  361.  
  362.         
  363.         def on_exit(callback):
  364.             if exited:
  365.                 raise ScopeError('State already exited')
  366.             elif not my_parent:
  367.                 raise ScopeError("State hasn't been entered yet")
  368.             
  369.             if callback not in exit_functions:
  370.                 exit_functions.append(callback)
  371.             
  372.  
  373.         this = State(getRule = getRule, setRule = setRule, swap = swap, child = child, __enter__ = __enter__, __exit__ = __exit__, on_exit = on_exit)
  374.         enabled = (this, getRule, getValue, active_child)
  375.         disabled = (None, getRule, disallow, active_child)
  376.         return this
  377.  
  378.     State.get = staticmethod(get)
  379.     State.root = root = new_state()
  380.     root.child = empty
  381.     root_getrule = root.getRule
  382.     del root.swap
  383.     del root.__enter__
  384.     del root.__exit__
  385.     return (lookup, empty)
  386.  
  387. (lookup, empty) = _let_there_be_state()
  388. del _let_there_be_state
  389.  
  390. class _GeneratorContextManager(object):
  391.     
  392.     def __init__(self, gen):
  393.         self.gen = gen
  394.  
  395.     
  396.     def __enter__(self):
  397.         for value in self.gen:
  398.             return value
  399.         else:
  400.             raise RuntimeError("generator didn't yield")
  401.  
  402.     
  403.     def __exit__(self, typ, value, traceback):
  404.         if typ is None:
  405.             for value in self.gen:
  406.                 raise RuntimeError("generator didn't stop")
  407.             
  408.         else:
  409.             
  410.             try:
  411.                 old = _swap_exc_info((typ, value, traceback))
  412.                 
  413.                 try:
  414.                     self.gen.next()
  415.                 finally:
  416.                     _swap_exc_info(old)
  417.  
  418.                 raise RuntimeError("generator didn't stop after throw()")
  419.             except StopIteration:
  420.                 exc = None
  421.                 return exc is not value
  422.             except:
  423.                 if sys.exc_info()[1] is not value:
  424.                     raise 
  425.                 
  426.  
  427.  
  428.  
  429. manager = contextlib.contextmanager
  430.  
  431. def with_(ctx, func):
  432.     inp = ctx.__enter__()
  433.     
  434.     try:
  435.         retval = func(inp)
  436.     except:
  437.         if not ctx.__exit__(*sys.exc_info()):
  438.             raise 
  439.         
  440.  
  441.     ctx.__exit__(None, None, None)
  442.     return retval
  443.  
  444.  
  445. def reraise():
  446.     (typ, val, tb) = _exc_info.get(get_ident(), nones)
  447.     if typ:
  448.         
  449.         try:
  450.             raise typ, val, tb
  451.         finally:
  452.             del typ
  453.             del val
  454.             del tb
  455.  
  456.     
  457.  
  458.  
  459. def call_with(ctxmgr):
  460.     return with_.__get__(ctxmgr, type(ctxmgr))
  461.  
  462.  
  463. noop = lambda key, rule: rule
  464.  
  465. mngr = lambda key, rule: Action.manage(rule())
  466.  
  467. call = lambda key, rule: rule()
  468.  
  469. class Service(_ClassDelegate):
  470.     __slots__ = ()
  471.     
  472.     def __default__(cls):
  473.         return cls()
  474.  
  475.     __default__ = classmethod(__default__)
  476.     
  477.     def __fallback__(cls, inherit, key):
  478.         if inherit:
  479.             return inherit(key)
  480.         
  481.         return cls.__default__
  482.  
  483.     __fallback__ = classmethod(__fallback__)
  484.     __apply__ = staticmethod(call)
  485.     
  486.     def new(cls, factory = None):
  487.         if not factory:
  488.             pass
  489.         factory = cls
  490.         state = State.child().__enter__()
  491.         
  492.         try:
  493.             
  494.             state[cls.get.im_self] = lambda : factory()
  495.             yield cls.get()
  496.             (None,)
  497.             reraise()
  498.         except:
  499.             state.__exit__(*sys.exc_info())
  500.             raise 
  501.  
  502.         state.__exit__(None, None, None)
  503.  
  504.     new = classmethod(manager(new))
  505.  
  506.  
  507. class Scope(Service):
  508.     
  509.     def __init__(self):
  510.         self.state = State.get()
  511.         self.cache = { }
  512.  
  513.     
  514.     def __compute__(cls, key, func, input):
  515.         self = cls.get()
  516.         cache = self.cache
  517.         if cache is None:
  518.             raise ScopeError(self.__class__.__name__ + ' is already exited')
  519.         elif input is not self.state[key]:
  520.             raise ScopeError('Redefined rule in sub-state')
  521.         elif key in cache:
  522.             return cache[key]
  523.         else:
  524.             old = self.state.swap()
  525.             
  526.             try:
  527.                 cache[key] = value = self.manage(func(input))
  528.                 self.state.on_exit(self.atexit)
  529.                 return value
  530.             finally:
  531.                 old.swap()
  532.  
  533.  
  534.     __compute__ = classmethod(__compute__)
  535.     
  536.     def manage(self, ob):
  537.         return ob
  538.  
  539.     
  540.     def atexit(self, *exc):
  541.         self.cache = None
  542.  
  543.     
  544.     def __default__(cls):
  545.         raise RuntimeError('No %s is currently active' % cls.__name__)
  546.  
  547.     __default__ = classmethod(__default__)
  548.     
  549.     def resource(cls, func):
  550.         return setting(func, wrap = cls.__compute__)
  551.  
  552.     resource = classmethod(resource)
  553.     
  554.     def resource_registry(cls, func):
  555.         return registry(func, wrap = cls.__compute__)
  556.  
  557.     resource_registry = classmethod(resource_registry)
  558.  
  559.  
  560. class Action(Scope):
  561.     
  562.     def __init__(self):
  563.         self.managers = []
  564.         super(Action, self).__init__()
  565.  
  566.     
  567.     def atexit(self, *exc):
  568.         super(Action, self).atexit(*exc)
  569.         managers = self.managers
  570.         self.managers = None
  571.         while managers:
  572.             managers.pop().__exit__(*exc)
  573.  
  574.     
  575.     def manage(self, ob):
  576.         enter = getattr(ob, '__enter__', None)
  577.         if enter is None:
  578.             return ob
  579.         
  580.         ctx = ob
  581.         ob = ctx.__enter__()
  582.         self.managers.append(ctx)
  583.         return ob
  584.  
  585.  
  586. resource = Action.resource
  587. resource_registry = Action.resource_registry
  588.  
  589. def nop():
  590.     pass
  591.  
  592.  
  593. class setting(object):
  594.     __class__ = type(nop)
  595.     func_code = nop.func_code
  596.     func_defaults = ()
  597.     __argnames__ = (('value', 'expr'),)
  598.     
  599.     def __init__(self, func, wrap = None):
  600.         if func.func_code.co_argcount != len(self.__argnames__):
  601.             raise TypeError(type(self).__name__ + ' function must have exactly %d argument(s)' % len(self.__argnames__))
  602.         
  603.         for var, names in enumerate(zip(func.func_code.co_varnames, self.__argnames__)):
  604.             if var not in names:
  605.                 raise TypeError(type(self).__name__ + " function argument %d must be named '%s'" % (num + 1, "' or '".join(names)))
  606.                 continue
  607.         
  608.         if self.__argnames__:
  609.             if not (func.func_defaults) or len(func.func_defaults) != 1:
  610.                 raise TypeError(type(self).__name__ + ' function must have a default value for last argument')
  611.             
  612.         self.__function__ = func
  613.         self.__module__ = func.__module__
  614.         self.__name__ = func.__name__
  615.         self.__doc__ = func.__doc__
  616.         if wrap:
  617.             self.__wrap__ = wrap
  618.         
  619.  
  620.     __call__ = lookup
  621.     
  622.     def __apply__(self, key, input):
  623.         return self.__wrap__(key, self.__function__, input)
  624.  
  625.     
  626.     def __wrap__(self, key, func, input):
  627.         return func(input)
  628.  
  629.     
  630.     def __fallback__(self, inherit, key):
  631.         if inherit is None:
  632.             return self.__function__.func_defaults[0]
  633.         else:
  634.             return inherit(key)
  635.  
  636.     
  637.     def __ilshift__(self, value):
  638.         State[self] = value
  639.         return self
  640.  
  641.     
  642.     def __repr__(self):
  643.         if self.__module__:
  644.             return self.__module__ + '.' + self.__name__
  645.         
  646.         return self.__name__
  647.  
  648.     
  649.     def __mod__(self, other):
  650.         if self.__function__.func_code.co_varnames[len(type(self).__argnames__) - 1] == 'expr':
  651.             return 'lambda: ' + other
  652.         
  653.         return other
  654.  
  655.  
  656.  
  657. def _with_prefix(.0, suffix):
  658.     (pre, func) = .0
  659.     return func(pre + suffix)
  660.  
  661.  
  662. def _prefixer(prefix, func):
  663.     return _with_prefix.__get__((prefix, func), tuple)
  664.  
  665.  
  666. class wildcard(setting):
  667.     
  668.     def __init__(self, registry):
  669.         self.__module__ = registry.__module__
  670.         self.__name__ = registry.__name__ + '.*'
  671.         self.__function__ = registry.__function__
  672.         self.__namespace__ = registry
  673.  
  674.     
  675.     def __mod__(self, other):
  676.         return 'lambda suffix: ' + other
  677.  
  678.     
  679.     def __apply__(self, key, input):
  680.         return input
  681.  
  682.     
  683.     def __fallback__(self, inherit, key):
  684.         parent = self.__namespace__
  685.         if parent.__namespace__:
  686.             func = State.get(parent.__namespace__['*'])
  687.             if func is not None:
  688.                 prefix = self.__name__.split('.')[-2] + '.'
  689.                 return _prefixer(prefix, func)
  690.             
  691.         
  692.  
  693.  
  694.  
  695. class registry(setting):
  696.     __argnames__ = (('suffix',), ('value', 'expr'))
  697.     func_code = (lambda key, default: pass).func_code
  698.     func_defaults = (None,)
  699.     
  700.     def __init__(self, func, ns = None, name = '', wrap = None):
  701.         setting.__init__(self, func, wrap)
  702.         if not name:
  703.             pass
  704.         self.__name__ = self.__name__
  705.         self.__namespace__ = ns
  706.         self.__contents__ = {
  707.             '*': wildcard(self) }
  708.  
  709.     
  710.     def __getitem__(self, key):
  711.         if '.' in key:
  712.             for key in key.split('.'):
  713.                 self = self[key]
  714.             
  715.             return self
  716.         
  717.         
  718.         try:
  719.             return self.__contents__[key]
  720.         except KeyError:
  721.             s = self.__dict__[key] = self.__contents__[key] = registry(self.__function__, self, self.__name__ + '.' + key, self.__dict__.get('__wrap__'))
  722.             return s
  723.  
  724.  
  725.     
  726.     def __getattr__(self, key):
  727.         if key.startswith('__') and key.endswith('__'):
  728.             raise AttributeError(key)
  729.         
  730.         return self[key]
  731.  
  732.     
  733.     def __contains__(self, key):
  734.         if '.' in key:
  735.             for key in key.split('.'):
  736.                 if key not in self.__contents__:
  737.                     return False
  738.                 
  739.                 self = self[key]
  740.             else:
  741.                 return True
  742.         
  743.         return key in self.__contents__
  744.  
  745.     
  746.     def __iter__(self):
  747.         return [](_[1])
  748.  
  749.     
  750.     def __call__(self, key, default = None):
  751.         if key not in self:
  752.             return default
  753.         
  754.         return lookup(self[key])
  755.  
  756.     
  757.     def __apply__(self, key, input):
  758.         return self.__wrap__(key, self.__function__.__get__(''), input)
  759.  
  760.     
  761.     def __fallback__(self, inherit, key):
  762.         if self.__namespace__:
  763.             suffix = key.__name__[len(self.__namespace__.__name__) + 1:]
  764.             finder = State.get(self.__namespace__['*'])
  765.             if finder is not None:
  766.                 return finder(suffix)
  767.             
  768.         
  769.         if inherit is not None:
  770.             return inherit(key)
  771.         
  772.         while self.__namespace__:
  773.             self = self.__namespace__
  774.         suffix = key.__name__[len(self.__name__) + 1:]
  775.         return self.__function__(suffix)
  776.  
  777.     
  778.     def __setitem__(self, key, value):
  779.         if value is not self[key]:
  780.             raise TypeError('Registries are read-only')
  781.         
  782.  
  783.     
  784.     def __setattr__(self, key, value):
  785.         if key.startswith('__') and key.endswith('__'):
  786.             return object.__setattr__(self, key, value)
  787.         else:
  788.             self[key] = value
  789.  
  790.  
  791.  
  792. class Source(object):
  793.     __slots__ = ('filename', '__weakref__')
  794.     
  795.     def __init__(self, filename, source = None):
  796.         global linecache
  797.         import linecache
  798.         self.filename = filename
  799.         if source is not None:
  800.             cache_source(filename, source, self)
  801.         
  802.  
  803.     
  804.     def compile(self, *args, **kw):
  805.         return Line(''.join(self), self, 1).compile(*args, **kw)
  806.  
  807.     
  808.     def __getitem__(self, key):
  809.         return Line(linecache.getlines(self.filename)[key], self, key + 1)
  810.  
  811.     
  812.     def __repr__(self):
  813.         return 'Source(%r)' % self.filename
  814.  
  815.     
  816.     def recode(self, code, offset = 0):
  817.         import new
  818.         if not isinstance(code, new.code):
  819.             return code
  820.         
  821.         return code.co_nlocals(code.co_stacksize, code.co_flags, code.co_code, tuple, [], []([ self.recode(c, offset) for c in code.co_consts ] + [
  822.             self]), code.co_names, code.co_varnames, code.co_filename, code.co_name, code.co_firstlineno + offset, code.co_lnotab, code.co_freevars, code.co_cellvars)
  823.  
  824.  
  825.  
  826. class Line(str):
  827.     
  828.     def __new__(cls, text, source, line):
  829.         return str.__new__(cls, text)
  830.  
  831.     
  832.     def __init__(self, text, source, line):
  833.         self.source = source
  834.         self.line = line
  835.  
  836.     
  837.     def compile(self, *args, **kw):
  838.         code = compile(self, self.source.filename, *args, **kw)
  839.         return self.source.recode(code, self.line - 1)
  840.  
  841.     
  842.     def eval(self, *args):
  843.         return eval(self.compile('eval'), *args)
  844.  
  845.     
  846.     def splitlines(self, *args, **kw):
  847.         return [ Line(line, self.source, self.line + offset) for offset, line in enumerate(str.splitlines(self, *args, **kw)) ]
  848.  
  849.     for m in [
  850.         'capitalize',
  851.         'center',
  852.         'expandtabs',
  853.         'ljust',
  854.         'lower',
  855.         'lstrip',
  856.         'replace',
  857.         'rjust',
  858.         'rstrip',
  859.         'strip',
  860.         'swapcase',
  861.         'title',
  862.         'translate',
  863.         'upper',
  864.         'zfill',
  865.         '__add__',
  866.         '__radd__',
  867.         '__getslice__',
  868.         '__mod__',
  869.         '__rmod__']:
  870.         if hasattr(str, m):
  871.             locals()[m] = (lambda f: (lambda self: Line(f(self, *args, **kw), self.source, self.line))
  872. )(getattr(str, m))
  873.             continue
  874.     
  875.  
  876.  
  877. def replaces(target):
  878.     
  879.     def decorator(cls):
  880.         if not issubclass(cls, Service):
  881.             raise TypeError('context.replaces() can only be used in a context.Service subclass')
  882.         
  883.         cls.get = staticmethod(target.get)
  884.         return cls
  885.  
  886.     decorate_class = decorate_class
  887.     import peak.util.decorators
  888.     decorate_class(decorator)
  889.     cdict = sys._getframe(1).f_locals
  890.     if cdict.setdefault('get', target.get) is not target.get:
  891.         raise ValueError('replaces() must be used only once per class; there is already a value for ``get``: %r' % (cdict['get'],))
  892.     
  893.  
  894.